{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "_llm = ChatOpenAI(\n",
    "    api_key=\"ollama\",\n",
    "    model=\"qwen2.5:7b\",\n",
    "    base_url=\"http://192.168.10.13:60001/v1\",\n",
    "    # temperature=0.7\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='为了提供准确的上海 hoje 的天气信息，我需要检查最新的气象数据，因为气象信息会随时间而变化。您可以通过查询最新天气预报或访问如中国气象局、Weather.com 等可靠的气象网站来获取上海市今天的详细天气情况。\\n\\n根据当前知识的更新限制，我无法直接查询实时数据，请您自行查看气象服务平台以获取准确信息。如果有其他问题或者需要帮助解读气象信息，随时可以询问我！', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 95, 'prompt_tokens': 35, 'total_tokens': 130}, 'model_name': 'qwen2.5:7b', 'system_fingerprint': 'fp_ollama', 'finish_reason': 'stop', 'logprobs': None}, id='run-db9e77c1-1a94-4ec2-ab0c-ec6d72eeb2da-0', usage_metadata={'input_tokens': 35, 'output_tokens': 95, 'total_tokens': 130})"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "_llm.invoke(\"今天上海的天气如何？\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import Annotated\n",
    "from langchain_core.tools import tool\n",
    "\n",
    "@tool\n",
    "def weather(city:Annotated[str,\"被查询的城市,用中文输入\"]) -> str:\n",
    "    \"\"\"\n",
    "    用于查询输入城市今日的天气状况。\n",
    "    \"\"\"\n",
    "    if city==\"上海\":\n",
    "        return \"上海今日有台风12级\"\n",
    "    else:\n",
    "        return \"天气晴朗，风和日丽\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "_tools = [weather,]\n",
    "_llm_with_tools = _llm.bind_tools(_tools)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "_messages = [\n",
    "    (\"human\",\"今天北京的天气如何？\")    \n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_mgjmg53m', 'function': {'arguments': '{\"city\":\"北京\"}', 'name': 'weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 45, 'prompt_tokens': 168, 'total_tokens': 213}, 'model_name': 'qwen2.5:7b', 'system_fingerprint': 'fp_ollama', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-4f74fa31-a6be-4d85-a1cb-85e545bda796-0', tool_calls=[{'name': 'weather', 'args': {'city': '北京'}, 'id': 'call_mgjmg53m', 'type': 'tool_call'}], usage_metadata={'input_tokens': 168, 'output_tokens': 45, 'total_tokens': 213})"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rep = _llm_with_tools.invoke(_messages)\n",
    "\n",
    "rep"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[('human', '今天北京的天气如何？'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_mgjmg53m', 'function': {'arguments': '{\"city\":\"北京\"}', 'name': 'weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 45, 'prompt_tokens': 168, 'total_tokens': 213}, 'model_name': 'qwen2.5:7b', 'system_fingerprint': 'fp_ollama', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-4f74fa31-a6be-4d85-a1cb-85e545bda796-0', tool_calls=[{'name': 'weather', 'args': {'city': '北京'}, 'id': 'call_mgjmg53m', 'type': 'tool_call'}], usage_metadata={'input_tokens': 168, 'output_tokens': 45, 'total_tokens': 213}), '天气晴朗，风和日丽', AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_mgjmg53m', 'function': {'arguments': '{\"city\":\"北京\"}', 'name': 'weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 45, 'prompt_tokens': 168, 'total_tokens': 213}, 'model_name': 'qwen2.5:7b', 'system_fingerprint': 'fp_ollama', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-4f74fa31-a6be-4d85-a1cb-85e545bda796-0', tool_calls=[{'name': 'weather', 'args': {'city': '北京'}, 'id': 'call_mgjmg53m', 'type': 'tool_call'}], usage_metadata={'input_tokens': 168, 'output_tokens': 45, 'total_tokens': 213}), '天气晴朗，风和日丽', AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_mgjmg53m', 'function': {'arguments': '{\"city\":\"北京\"}', 'name': 'weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 45, 'prompt_tokens': 168, 'total_tokens': 213}, 'model_name': 'qwen2.5:7b', 'system_fingerprint': 'fp_ollama', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-4f74fa31-a6be-4d85-a1cb-85e545bda796-0', tool_calls=[{'name': 'weather', 'args': {'city': '北京'}, 'id': 'call_mgjmg53m', 'type': 'tool_call'}], usage_metadata={'input_tokens': 168, 'output_tokens': 45, 'total_tokens': 213}), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_mgjmg53m', 'function': {'arguments': '{\"city\":\"北京\"}', 'name': 'weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 45, 'prompt_tokens': 168, 'total_tokens': 213}, 'model_name': 'qwen2.5:7b', 'system_fingerprint': 'fp_ollama', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-4f74fa31-a6be-4d85-a1cb-85e545bda796-0', tool_calls=[{'name': 'weather', 'args': {'city': '北京'}, 'id': 'call_mgjmg53m', 'type': 'tool_call'}], usage_metadata={'input_tokens': 168, 'output_tokens': 45, 'total_tokens': 213}), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_mgjmg53m', 'function': {'arguments': '{\"city\":\"北京\"}', 'name': 'weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 45, 'prompt_tokens': 168, 'total_tokens': 213}, 'model_name': 'qwen2.5:7b', 'system_fingerprint': 'fp_ollama', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-4f74fa31-a6be-4d85-a1cb-85e545bda796-0', tool_calls=[{'name': 'weather', 'args': {'city': '北京'}, 'id': 'call_mgjmg53m', 'type': 'tool_call'}], usage_metadata={'input_tokens': 168, 'output_tokens': 45, 'total_tokens': 213}), '天气晴朗，风和日丽']\n"
     ]
    }
   ],
   "source": [
    "from langchain_core.messages import ToolMessage\n",
    "\n",
    "if rep.tool_calls is not None or len(rep.tool_calls)>0:\n",
    "    _messages.append(rep)\n",
    "    for _tool in rep.tool_calls:\n",
    "        _fun = eval(_tool[\"name\"])\n",
    "        _tool_rep = _fun.invoke(_tool[\"args\"])\n",
    "        # print(_tool_rep)\n",
    "        _messages.append(_tool_rep)\n",
    "# _tool_rep\n",
    "\n",
    "_llm.invoke(_messages)\n",
    "print(_messages)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py310",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
